#!/usr/bin/python
'''A library that provides python interface to Smster API
Based on python-twitter'''

__author__  = 'gurianov@gmail.com'
__version__ = '0.0.1-develop'

try:
    from hashlib import md5
except ImportError:
    from md5 import md5
import urllib, urllib2
import urlparse
from xml.dom import minidom

class SmsterError (Exception):
    '''Base class for Smster errors'''

class Status (object):
    '''A class representing the Status structure used by Smster API.
    The Status structure exposes the following properties:

        self.id
        self.created_at
        self.created_at_in_seconds #read-only
        self.text
        self.source
        self.sender_id
        self.sender_name
        self.sender_nick
        self.comment_to
    '''
    def __init__(self,
                 id = None,
                 created_at = None,
                 text = None,
                 source = None,
                 sender_id = None,
                 sender_name = None,
                 sender_nick = None,
                 comment_to = None):
        self.id = id
        self.created_at = created_at
        self.text = text
        self.source = source
        self.sender_id = sender_id
        self.sender_name = sender_name
        self.sender_nick = sender_nick
        self.comment_to = comment_to

    def __ne__(self, other):
        return not self.__eq__(other)

    def __eq__(self, other):
        try:
            return other and \
                   self.id == other.id and \
                   self.created_at == other.created_at and \
                   self.text == other.text and \
                   self.source == other.source and \
                   self.sender_id == other.sender_id and \
                   self.sender_name == other.sender_name and \
                   self.sender_nick == other.sender_nick and \
                   self.comment_to == other.comment_to
        except AttributeError:
            return False

    def __str__(self):
        return self.id + self.sender_name + self.sender.text


    def AsDict(self):
        data = {}
        if self.created_at:
            data['created_at'] = self.created_at
        if self.id:
            data['id'] = self.id
        if self.text:
            data['text'] = self.text
        if self.source:
            data['source'] = self.source
        if self.sender_id:
            data['sender_id'] = self.sender_id
        if self.sender_name:
            data['sender_name'] = self.sender_name
        if self.sender_nick:
            data['sender_nick'] = self.sender_nick
        if self.sender_comment_to:
            data['comment_to'] = self.comment_to
        return data

    @staticmethod
    def NewFromXML(data):

        return Status(created_at = data.get('created_at', None),
                      id = data.get('id', None),
                      text = data.get('text', None),
                      user = user)

class User (object):
    def __init__(self):
        self.id
        self.name
        self.nick
        self.http
        self.city
        self.avatar
        self.private
        self.options

class Message (object):
    def __init__(self):
        self.id
        self.created
        self.text
        self.sender_id
        self.recipient_id

class Api(object):
    ''' Smster API class'''
    API_URL = 'http://api.smster.ru'
    API_KEY = '6154hd5dmf5azrn'
    SECRET_WORD = '8nar488y4b18y49'
    def __init__(self, username = None,
                 password = None):
        self.api_url = Api.API_URL
        self.api_key = Api.API_KEY
        self.secret_word= Api.SECRET_WORD
    
    def _SignParameters(self, parameters):
        '''Returns api_sig signature for provided parameters'''
        string = self.secret_word
        for key in [key for key in sorted(parameters) if parameters[key]]:
            string += key + parameters[key]
        return md5(string).hexdigest()
    
    def _Encode (self, s):
        return unicode(s).encode('utf-8')
    
    def _EncodeParameters(self, parameters):
        return urllib.urlencode(dict([(k, self._Encode(v)) for k, v in parameters.items() if v is not None]))
    
    def _BuildUrl (self, method = None, extra_path = None, parameters = None):
        (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(self.api_url)
        if extra_path:
            path = extra_path
        query = parameters
        return urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
    
    def _FetchUrl (self,
                   method = None,
                   path = '/',
                   parameters = None,
                   is_post = False,):
        if not parameters: parameters = {}
        parameters['method'] = method
        parameters['api_key'] = self.api_key
        api_sig = self._SignParameters(parameters)
        parameters['api_sig'] = api_sig
        encoded_parameters = self._EncodeParameters(parameters)
        if is_post:
            url = self._BuildUrl(method, path)
            post_data = encoded_parameters
        else:
            url = self._BuildUrl(method, path, encoded_parameters)
            post_data = None
        opener = urllib2.build_opener()
        data = opener.open(url, post_data).read()
        #print data
        return data
    
    def GetFrob(self):
        xml = minidom.parseString(self._FetchUrl (method = 'auth.getFrob'))
        frob = xml.getElementsByTagName('frob')[0].firstChild.data
        return frob
    
    def GetToken(self, frob):
        xml = minidom.parseString(self._FetchUrl (method = 'auth.getToken',
                                                  parameters = {'frob':frob}))
        frob = xml.getElementsByTagName('token')[0].firstChild.data
        user_id = xml.getElementsByTagName('user')[0].attributes['uid'].value
        return frob, user_id
    
    def JavaLogin (self, username, password, frob):
        xml = minidom.parseString(self._FetchUrl(path = '/login_java.php',
                                  parameters = {'phone':username, 'pwd':password, 'frob':frob},
                                  is_post = True))
        
        return

if __name__ == '__main__':
    api_key = '6154hd5dmf5azrn'
    secret_word = '8nar488y4b18y49'
    parameters = {
                 'api_key': api_key,
                 'method': 'auth.getFrob',
                 }
    api = Api()
    #print api._FetchUrl('auth.getFrob')
    frob = api.GetFrob()
    #print frob
    api.JavaLogin('phone','pass', frob)
    token = api.GetToken(frob)[0]
    
